package com.sharer.last.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sharer.last.base.enums.BusinessExceptionCode;
import com.sharer.last.base.enums.ExceptionPrefixParamEnum;
import com.sharer.last.base.exception.BusinessException;
import com.sharer.last.base.model.PageVO;
import com.sharer.last.base.support.QueryCondition;
import com.sharer.last.base.utils.ConvertUtil;
import com.sharer.last.mapper.OperationLogMapper;
import com.sharer.last.model.dto.log.OperationLogChangeDTO;
import com.sharer.last.model.dto.log.OperationLogQueryDTO;
import com.sharer.last.model.dto.UserAgentDTO;
import com.sharer.last.model.po.OperationLogPO;
import com.sharer.last.model.vo.log.OperationLogVO;
import com.sharer.last.service.OperationLogService;
import com.sharer.last.utils.BeanUtil;
import com.sharer.last.utils.IpAddressUtils;
import com.sharer.last.utils.UserAgentUtils;
import com.sharer.last.wrapper.OperationLogWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.annotation.Resource;

/**
 * 操作日志业务层实现
 *
 * @ClassName OperationLogServiceImpl
 * @Author wangjin
 * @Date 2023/5/5 20:45
 * @Description
 * @Version 1.0
 */
@Service
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLogPO> implements OperationLogService {
    @Resource
    OperationLogMapper operationLogMapper;

    @Resource
    OperationLogWrapper operationLogWrapper;

    @Resource
    UserAgentUtils userAgentUtils;

    /**
     * 分页查询
     *
     * @param queryDTO
     * @return
     */
    @Override
    public PageVO<OperationLogVO> selectListByPage(OperationLogQueryDTO queryDTO) {
        LambdaQueryWrapper<OperationLogPO> qw   = this.buildQueryWrapper(queryDTO);
        IPage<OperationLogPO>              page = this.page(QueryCondition.getPage(queryDTO.getPage()), qw);
        return operationLogWrapper.toPageVO(page);
    }

    private LambdaQueryWrapper<OperationLogPO> buildQueryWrapper(OperationLogQueryDTO queryDTO) {
        LambdaQueryWrapper<OperationLogPO> qw        = new LambdaQueryWrapper<>();
        String                             startTime = queryDTO.getStartTime();
        if (startTime != null) {
            qw.gt(OperationLogPO::getCreateTime, startTime);
        }
        String endTime = queryDTO.getEndTime();
        if (endTime != null) {
            qw.lt(OperationLogPO::getCreateTime, endTime);
        }
        return qw;
    }

    /**
     * 新增日志
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createOperationLog(OperationLogChangeDTO dto) {
        OperationLogPO po           = BeanUtil.copy(dto, OperationLogPO.class);
        String         ipSource     = IpAddressUtils.getCityInfo(dto.getIp());
        UserAgentDTO   userAgentDTO = userAgentUtils.parseOsAndBrowser(dto.getUserAgent());
        po.setIpSource(ipSource);
        po.setOs(userAgentDTO.getOs());
        po.setBrowser(userAgentDTO.getBrowser());
        if (!this.save(po)) {
            throw new BusinessException(BusinessExceptionCode.DATA_REMOVE_FAIL, ExceptionPrefixParamEnum.OPERATION_LOG);
        }
    }

    /**
     * 删除日志
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeOperationLogById(Long id) {
        if (ConvertUtil.toInt(id) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.OPERATION_LOG);
        }
        // 查询数据是否存在
        OperationLogPO operationLogPO = this.getById(id);
        if (operationLogPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.OPERATION_LOG);
        }
        if (!this.removeById(id)) {
            throw new BusinessException(BusinessExceptionCode.DATA_REMOVE_FAIL, ExceptionPrefixParamEnum.OPERATION_LOG);
        }
    }
}
